Data Read-in

https://docs.google.com/spreadsheets/d/1nDXokcwtq_J8A6Uh7zAxsWW16MtcEC_1EiLstz4WGig/edit#gid=1782979571

Social_2022_rawNA_data <- readr::read_csv("DATA/Social Query 2022 NA Campaigns.csv") %>%
  clean_names() %>% 
  filter(date < '2022-07-01') %>% 
  filter(impressions_analyzed > 10)
Rows: 24117 Columns: 149
-- Column specification ---------------------------------------------------------------------
Delimiter: ","
chr   (4): olive_plan_name, platform, olive_placement_type, last_file_date
dbl  (99): olive_plan_id, olive_placement_id, brand_id, opid, _1_sec_in_view_impressions,...
lgl  (44): active_view_eligible_impressions, active_view_measurable_impressions, active_v...
date  (2): date, ingestion_date

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
Social_2022_rawNA_lookup <- readr::read_csv("DATA/CampaignLookup.csv") %>%
  clean_names()
Rows: 9 Columns: 4
-- Column specification ---------------------------------------------------------------------
Delimiter: ","
chr (3): Name, Spend, Quarter
dbl (1): OPID

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
Social_2022_MOAT_lookup = googlesheets4::read_sheet(
  "https://docs.google.com/spreadsheets/d/1nDXokcwtq_J8A6Uh7zAxsWW16MtcEC_1EiLstz4WGig/edit#gid=1782979571") %>% 
  clean_names() %>% 
  filter(social == 'Y')
Auto-refreshing stale OAuth token.
√ Reading from Benchmark_Moat_Tile_2022.
√ Range Benchmark_Moat_Tile_2022.

Summary Stats

Placement types distinct


Social_2022_rawNA_data %>%
  group_by(platform,olive_placement_type) %>% 
  summarize (counts = n())
`summarise()` has grouped output by 'platform'. You can override using the `.groups` argument.
Social_2022_rawNA_data %>%
  group_by(platform,brand_id) %>% 
  summarize (counts = n()) %>%
  left_join(Social_2022_MOAT_lookup, by = 'brand_id')
`summarise()` has grouped output by 'platform'. You can override using the `.groups` argument.

Social_2022_processedNA_data <-
  Social_2022_rawNA_data %>%
  select(
    olive_plan_id:opid, impressions_analyzed,
    x2_sec_video_in_view_impressions, in_view_impressions, fully_on_screen_3sec_cumulative, player_vis_and_aud_on_complete_sum,
    valid_and_avoc, valid_and_viewable, valid_and_viewable_gm, valid_and_fully_on_screen_3sec_cumulative, valid_and_inview_3sec_cumulative
  ) %>%
  rename(platform_old = platform
         ) %>% 
  left_join(Social_2022_MOAT_lookup, by = 'brand_id'
  ) %>% 
  mutate(
    olive_plan_id = as.character(olive_plan_id),
    olive_placement_id = as.character(olive_placement_id),
    brand_id = as.character(brand_id) ,
    opid = as.character(opid)
  )

#Look at global moat

Social_2022_processedNA_data %>% 
  skim()
-- Data Summary ------------------------
                           Values    
Name                       Piped data
Number of rows             16137     
Number of columns          24        
_______________________              
Column type frequency:               
  character                13        
  Date                     1         
  numeric                  10        
________________________             
Group variables            None      

-- Variable type: character ---------------------------------------------------------------------------------------
# A tibble: 13 x 8
   skim_variable        n_missing complete_rate   min   max empty n_unique whitespace
 * <chr>                    <int>         <dbl> <int> <int> <int>    <int>      <int>
 1 olive_plan_id                0             1     5     5     0        8          0
 2 olive_plan_name              0             1    44    72     0        8          0
 3 platform_old                 0             1     6    18     0        7          0
 4 olive_placement_id           0             1     7     7     0      364          0
 5 olive_placement_type         0             1    15    27     0        3          0
 6 brand_id                     0             1     5     7     0       14          0
 7 opid                         0             1     7     7     0      364          0
 8 dataset_name                 0             1    20    51     0       14          0
 9 region                       0             1     2     6     0        2          0
10 channel                      0             1     5     7     0        2          0
11 social                       0             1     1     1     0        1          0
12 platform                     0             1     6     9     0        6          0
13 media_type                   0             1     5    15     0        4          0

-- Variable type: Date --------------------------------------------------------------------------------------------
# A tibble: 1 x 7
  skim_variable n_missing complete_rate min        max        median     n_unique
* <chr>             <int>         <dbl> <date>     <date>     <date>        <int>
1 date                  0             1 2022-01-18 2022-06-30 2022-03-03      164

-- Variable type: numeric -----------------------------------------------------------------------------------------
# A tibble: 10 x 11
   skim_variable                             n_missing complete_rate    mean      sd    p0   p25    p50     p75
 * <chr>                                         <int>         <dbl>   <dbl>   <dbl> <dbl> <dbl>  <dbl>   <dbl>
 1 impressions_analyzed                              0         1     209721. 518214.    11 2222  27191  166005 
 2 x2_sec_video_in_view_impressions               6641         0.588  56682. 191926.     0  255.  4414   26352.
 3 in_view_impressions                           10589         0.344 106745. 228837.     1  311. 39378  121618.
 4 fully_on_screen_3sec_cumulative                9578         0.406  39246. 135769.     0   41   1339   17771 
 5 player_vis_and_aud_on_complete_sum             8659         0.463    864.   2336.     0    0     43     452 
 6 valid_and_avoc                                 8659         0.463    862.   2322.     0    0     43     452 
 7 valid_and_viewable                              257         0.984  71189. 202864.     0  124   7672.  55972.
 8 valid_and_viewable_gm                         11095         0.312 190179. 444404.     0  149  41944  117986.
 9 valid_and_fully_on_screen_3sec_cumulative      9578         0.406  39245. 135767.     0   41   1339   17771 
10 valid_and_inview_3sec_cumulative               6221         0.614  19872.  83958.     0   57   1502   13010 
      p100 hist 
 *   <dbl> <chr>
 1 9704935 ▇▁▁▁▁
 2 6361782 ▇▁▁▁▁
 3 6120199 ▇▁▁▁▁
 4 5942621 ▇▁▁▁▁
 5   34734 ▇▁▁▁▁
 6   34040 ▇▁▁▁▁
 7 6361782 ▇▁▁▁▁
 8 7095033 ▇▁▁▁▁
 9 5942621 ▇▁▁▁▁
10 5942621 ▇▁▁▁▁

Plot Impression Level Data


p = Social_2022_processedNA_data %>% 
  ggplot() +
    aes(x = date, y = impressions_analyzed, color = olive_plan_name, fill = olive_plan_name) +
  xlab("Date") +
  ylab("Impressions") +
  ggtitle("Impressions by Campaign") + #fix size
geom_bar(stat = 'identity') +
  theme_bw() +
  theme(
     plot.title = element_text(size=22, hjust = 0.5),
     axis.title.y = element_blank()
  )

p

ggplotly(p)

Calculate V/V and AVOC Rates by Platform

Social_2022_SummarizedNA_date <-
Social_2022_processedNA_data %>%
  mutate(
    valid_viewable_imps =
      case_when(
        platform == 'Twitter' & channel == 'Display' ~ valid_and_inview_3sec_cumulative,
        platform == 'LinkedIn' ~ x2_sec_video_in_view_impressions,
        TRUE ~ valid_and_viewable
      ),
    avoc_imps = case_when(
    TRUE ~  player_vis_and_aud_on_complete_sum 
    ),
    quarter = lubridate::quarter(date),
    channel = case_when(
      channel == 'DISPLAY' ~ 'STATIC',
      TRUE ~ channel
    )
  ) %>% 
  group_by(olive_plan_name,date, channel, platform) %>% 
  summarize(
    valid_viewable_imps = sum(valid_viewable_imps),
    avoc_imps = sum(avoc_imps),
    impressions = sum(impressions_analyzed),
    quarter = max(quarter)
  ) %>% 
  arrange(date,olive_plan_name)

Social_2022_SummarizedNA_date %>% 
  filter(platform == 'Twitter') %>% 
  filter(channel == 'DISPLAY')

Social_2022_SummarizedNA_date %>% 
  group_by(quarter, platform, channel) %>% 
  summarize(
    `Valid and Viewable Rate` = sum(valid_viewable_imps)/sum(impressions),
    `AVOC Rate` = sum(avoc_imps)/sum(impressions)
  ) %>%     
  kbl() %>% 
 kable_material(c("striped", "hover","condensed","responsive"),full_width = F,fixed_thead = T)
write_sheet(Social_2022_SummarizedNA_date, ss = 'https://docs.google.com/spreadsheets/d/1OT7zoqbcnadQsR8ehHbvMfKn8mieWYa-dVaCOHFdhHI/edit#gid=1469978055',
           sheet = 'Aggregated Data NA')

Additional Twitter Level Information


Social_2022_rawNA_DV30_data <- readr::read_csv("DATA/Social Query 2022 NA DV360.csv") %>%
  clean_names() %>% 
  filter(date < '2022-07-01') %>% 
  mutate(
    olive_placement_id = as.character(olive_placement_id)
  )
  

Social_2022_processedTwitterNA_data <-
Social_2022_processedNA_data %>% select(olive_plan_name,olive_placement_id,date,impressions_analyzed) %>%
  mutate(
    quarter = quarter(date)
  ) %>% 
  group_by(olive_plan_name,olive_placement_id,date,quarter) %>% 
  summarize(
    impressions_analyzed = sum(impressions_analyzed)
  ) %>%
  ungroup() %>% 
  left_join(Social_2022_rawNA_DV30_data, by = c('olive_placement_id','olive_plan_name', 'date')) %>% 
  filter(!is.na(olive_plan_name)) %>% 
  filter(platform == 'Twitter - Official' & olive_placement_type == 'Standard Banner (BAN)') %>% 
  mutate(
    impressions = impressions_analyzed,
    platform = 'Twitter',
    channel = 'STATIC',
    avoc_imps = NA,
    valid_viewable_imps = valid_and_viewable_impressions,
    Time = NA
  ) %>% 
  select(olive_plan_name,   date,   channel,    platform,   valid_viewable_imps,    avoc_imps,  impressions,    Time,   quarter)

Social_2022_SummarizedNA_data_updatedTwitter <-
Social_2022_SummarizedNA_date %>%
  filter(!(platform == 'Twitter' & channel == 'STATIC')) %>%   
  bind_rows (Social_2022_processedTwitterNA_data)

Update Twitter Information



write_sheet(Social_2022_SummarizedNA_data_updatedTwitter, ss = 'https://docs.google.com/spreadsheets/d/1OT7zoqbcnadQsR8ehHbvMfKn8mieWYa-dVaCOHFdhHI/edit#gid=1469978055',
           sheet = 'Additional NA Twitter Data')

H1 2022 Meta Ask (Top 7 Campaigns)

Data Read-in

Google Sheet with BQ Results

Social_2022_raw_Top7Meta_data = googlesheets4::read_sheet(
  "https://docs.google.com/spreadsheets/d/1RU0QGpnn7FHtZaZfCA22kCcGpEeY1vLh0pHkJ9DEZfU/edit#gid=1752984558") %>% 
  clean_names() %>% 
  filter(impressions_analyzed > 10)


Social_2022_MOAT_lookup = googlesheets4::read_sheet(
  "https://docs.google.com/spreadsheets/d/1nDXokcwtq_J8A6Uh7zAxsWW16MtcEC_1EiLstz4WGig/edit#gid=1782979571") %>% 
  clean_names() %>% 
  filter(social == 'Y')

Social_2022_raw_Top7Meta_data %>% 
  group_by(platform) %>% 
  summarize(dist = n())

Social_2022_processed_Top7Meta_data <-
  Social_2022_raw_Top7Meta_data %>%
  filter(platform == 'Facebook') %>% 
  select(
    olive_plan_id:opid, impressions_analyzed,
    x2_sec_video_in_view_impressions, in_view_impressions, fully_on_screen_3sec_cumulative, player_vis_and_aud_on_complete_sum,
    valid_and_avoc, valid_and_viewable, valid_and_viewable_gm, valid_and_fully_on_screen_3sec_cumulative, valid_and_inview_3sec_cumulative
  ) %>%
  rename(platform_old = platform
         ) %>% 
  left_join(Social_2022_MOAT_lookup, by = 'brand_id'
  ) %>% 
  mutate(
    olive_plan_id = as.character(olive_plan_id),
    olive_placement_id = as.character(olive_placement_id),
    brand_id = as.character(brand_id) ,
    opid = as.character(opid)
  )

#Check Missing Data

Social_2022_processed_Top7Meta_data %>% 
  skim()
-- Data Summary ------------------------
                           Values    
Name                       Piped data
Number of rows             4273      
Number of columns          24        
_______________________              
Column type frequency:               
  character                13        
  numeric                  10        
  POSIXct                  1         
________________________             
Group variables            None      

-- Variable type: character -----------------------------------------------------------------------------------------------------------------------
# A tibble: 13 x 8
   skim_variable        n_missing complete_rate   min   max empty n_unique whitespace
 * <chr>                    <int>         <dbl> <int> <int> <int>    <int>      <int>
 1 olive_plan_id                0             1     4     5     0        7          0
 2 olive_plan_name              0             1    43    68     0        7          0
 3 platform_old                 0             1     8     8     0        1          0
 4 olive_placement_id           0             1     7     7     0      124          0
 5 olive_placement_type         0             1    12    21     0        3          0
 6 brand_id                     0             1     7     7     0        5          0
 7 opid                         0             1     7     7     0      124          0
 8 dataset_name                 0             1    32    51     0        5          0
 9 region                       0             1     2     2     0        1          0
10 channel                      0             1     5     7     0        2          0
11 social                       0             1     1     1     0        1          0
12 platform                     0             1     8     9     0        2          0
13 media_type                   0             1     5    13     0        3          0

-- Variable type: numeric -------------------------------------------------------------------------------------------------------------------------
# A tibble: 10 x 11
   skim_variable                             n_missing complete_rate    mean      sd    p0    p25     p50     p75    p100 hist   
 * <chr>                                         <int>         <dbl>   <dbl>   <dbl> <dbl>  <dbl>   <dbl>   <dbl>   <dbl> <chr>  
 1 impressions_analyzed                              0         1     172452. 310322.    11   5698  39769  190414  2458527 "▇▁▁▁▁"
 2 x2_sec_video_in_view_impressions                473         0.889  14846.  25037.     0    539   3280.  19332.  255752 "▇▁▁▁▁"
 3 in_view_impressions                            3800         0.111 320224. 223119.  5632 137023 269619  443635  1111029 "▇▆▃▁▁"
 4 fully_on_screen_3sec_cumulative                4273         0        NaN      NA     NA     NA     NA      NA       NA " "    
 5 player_vis_and_aud_on_complete_sum              473         0.889   1255.   2535.     0     24    323    1200.   24082 "▇▁▁▁▁"
 6 valid_and_avoc                                  473         0.889   1255.   2535.     0     24    323    1200.   24082 "▇▁▁▁▁"
 7 valid_and_viewable                                0         1      48649. 123451.     0    697   4979   28720  1111029 "▇▁▁▁▁"
 8 valid_and_viewable_gm                          3800         0.111 667387. 469658. 11014 294637 561180  924167  2296318 "▇▆▃▁▁"
 9 valid_and_fully_on_screen_3sec_cumulative      4273         0        NaN      NA     NA     NA     NA      NA       NA " "    
10 valid_and_inview_3sec_cumulative                473         0.889  10966.  17556.     0    410   2431   15043.  198035 "▇▁▁▁▁"

-- Variable type: POSIXct -------------------------------------------------------------------------------------------------------------------------
# A tibble: 1 x 7
  skim_variable n_missing complete_rate min                 max                 median              n_unique
* <chr>             <int>         <dbl> <dttm>              <dttm>              <dttm>                 <int>
1 date                  0             1 2020-04-27 00:00:00 2021-06-30 00:00:00 2020-12-09 00:00:00      197

Plot Impression Level Data


p = Social_2022_processed_Top7Meta_data %>% 
  ggplot() +
    aes(x = date, y = impressions_analyzed, color = olive_plan_name, fill = olive_plan_name) +
  xlab("Date") +
  ylab("Impressions") +
  ggtitle("Meta Impressions by Campaign") + #fix size
geom_bar(stat = 'identity') +
  theme_bw() +
  theme(
     plot.title = element_text(size=22, hjust = 0.5),
     axis.title.y = element_blank()
  )

p


ggplotly(p)

Calculate V/V and AVOC Rates by Platform

Social_2022_Summarized_Top7Meta_data <-
Social_2022_processed_Top7Meta_data %>%
  mutate(
    valid_viewable_imps =
      case_when(
        platform == 'Twitter' & channel == 'Display' ~ valid_and_inview_3sec_cumulative,
        platform == 'LinkedIn' ~ x2_sec_video_in_view_impressions,
        TRUE ~ valid_and_viewable
      ),
    avoc_imps = case_when(
    is.na(player_vis_and_aud_on_complete_sum) ~ 0,
    TRUE ~  player_vis_and_aud_on_complete_sum 
    ),
    quarter = lubridate::quarter(date),
    channel = case_when(
      channel == 'DISPLAY' ~ 'STATIC',
      TRUE ~ channel
    )
  ) %>% 
  group_by(olive_plan_name,date, channel, platform) %>% 
  summarize(
    valid_viewable_imps = sum(valid_viewable_imps),
    avoc_imps = sum(avoc_imps),
    impressions = sum(impressions_analyzed),
    quarter = max(quarter)
  ) %>% 
  arrange(date,olive_plan_name)
`summarise()` has grouped output by 'olive_plan_name', 'date', 'channel'. You can override using the `.groups` argument.

Summarized Table - Campaign

Sumif Documentation


Social_2022_Summarized_Top7Meta_data %>% 
  group_by(olive_plan_name) %>% 
  summarize(
    `Valid and Viewable Rate` = sum(valid_viewable_imps)/sum(impressions),
    `Video vs Static` = 1 - sum(impressions[channel =='STATIC'])/sum(impressions)
  ) %>%     
  kbl() %>% 
 kable_material(c("striped", "hover","condensed","responsive"),full_width = F,fixed_thead = T)
olive_plan_name Valid and Viewable Rate Video vs Static
Chromebook NA Q4 2020 United States - Brand 0.14829 1.0000
Google FI Q2 2021 United States - Brand Demand Gen 0.11471 1.0000
Grow with Google NA Q2 2021 United States - Career Certifications 0.19344 1.0000
Pixel US Ramble Q1 2021 North America - Brand 0.41812 0.0666
Pixel US Ramble Q2 2021 North America - Brand 0.46276 0.0000
YouTube NA 2020 Q4 2020 United States - Longtail_Brand Voice_#669762 0.12791 1.0000
YouTube NA Q2 2020 United States - Longtail_James Charles_#669762 0.11704 1.0000

Write to Google Sheets


Social_2022_Summarized_Top7Meta_data_Table <-
Social_2022_Summarized_Top7Meta_data %>% 
  group_by(olive_plan_name) %>% 
  summarize(
    `Valid and Viewable Rate` = sum(valid_viewable_imps)/sum(impressions),
    `Video vs Static` = 1 - sum(impressions[channel =='STATIC'])/sum(impressions)
  )
write_sheet(Social_2022_Summarized_Top7Meta_data_Table, ss = 'https://docs.google.com/spreadsheets/d/1RU0QGpnn7FHtZaZfCA22kCcGpEeY1vLh0pHkJ9DEZfU/edit#gid=1752984558',
           sheet = 'Aggregated Data From R')

H1 2022 Meta Ask (Additional 2 Campaigns)

Data Read-in

Google Sheet with BQ Results

Social_2022_raw_Add2Meta_data = googlesheets4::read_sheet(
  "https://docs.google.com/spreadsheets/d/1YdkESoYlv6fzpQY84j4AB7Lw5qfW8XKPmh2B0gApYJA/edit#gid=1980208140") %>% 
  clean_names() %>% 
  filter(impressions_analyzed > 10)
√ Reading from Meta Ask Two Additional Campaigns.
√ Range Results.

Social_2022_raw_Add2Meta_data %>% 
  group_by(platform) %>% 
  summarize(dist = n())

Social_2022_processed_Add2Meta_data <-
  Social_2022_raw_Add2Meta_data %>%
  filter(platform == 'Facebook'|platform == 'Facebook/Instagram') %>% 
  select(
    olive_plan_id:opid, impressions_analyzed,
    x2_sec_video_in_view_impressions, in_view_impressions, fully_on_screen_3sec_cumulative, player_vis_and_aud_on_complete_sum,
    valid_and_avoc, valid_and_viewable, valid_and_viewable_gm, valid_and_fully_on_screen_3sec_cumulative, valid_and_inview_3sec_cumulative
  ) %>%
  rename(platform_old = platform
         ) %>% 
  left_join(Social_2022_MOAT_lookup, by = 'brand_id'
  ) %>% 
  mutate(
    olive_plan_id = as.character(olive_plan_id),
    olive_placement_id = as.character(olive_placement_id),
    brand_id = as.character(brand_id) ,
    opid = as.character(opid)
  )

#Check Missing Data

Social_2022_processed_Add2Meta_data %>% 
  skim()
-- Data Summary ------------------------
                           Values    
Name                       Piped data
Number of rows             8532      
Number of columns          24        
_______________________              
Column type frequency:               
  character                13        
  numeric                  10        
  POSIXct                  1         
________________________             
Group variables            None      

-- Variable type: character -------------------------------------------------------------------------------------------------------------
# A tibble: 13 x 8
   skim_variable        n_missing complete_rate   min   max empty n_unique whitespace
 * <chr>                    <int>         <dbl> <int> <int> <int>    <int>      <int>
 1 olive_plan_id                0             1     5     5     0        2          0
 2 olive_plan_name              0             1    53    59     0        2          0
 3 platform_old                 0             1     8    18     0        2          0
 4 olive_placement_id           0             1     7     7     0      124          0
 5 olive_placement_type         0             1    15    21     0        2          0
 6 brand_id                     0             1     7     7     0        7          0
 7 opid                         0             1     7     7     0      124          0
 8 dataset_name                 0             1    32    51     0        7          0
 9 region                       0             1     2     2     0        1          0
10 channel                      0             1     5     7     0        2          0
11 social                       0             1     1     1     0        1          0
12 platform                     0             1     8     9     0        2          0
13 media_type                   0             1     5    15     0        4          0

-- Variable type: numeric ---------------------------------------------------------------------------------------------------------------
# A tibble: 10 x 11
   skim_variable                             n_missing complete_rate    mean      sd    p0   p25    p50     p75    p100 hist   
 * <chr>                                         <int>         <dbl>   <dbl>   <dbl> <dbl> <dbl>  <dbl>   <dbl>   <dbl> <chr>  
 1 impressions_analyzed                              0         1     137611. 381278.    11  855.  9138.  89822  4318856 "▇▁▁▁▁"
 2 x2_sec_video_in_view_impressions               2422         0.716  13879.  42668.     0   68    688.   6622.  527738 "▇▁▁▁▁"
 3 in_view_impressions                            6114         0.283  87725. 229315.     1 1381.  8528   59999  2078543 "▇▁▁▁▁"
 4 fully_on_screen_3sec_cumulative                8532         0        NaN      NA     NA   NA     NA      NA       NA " "    
 5 player_vis_and_aud_on_complete_sum             2418         0.717   1066.   3791.     0    0     29     534.   70156 "▇▁▁▁▁"
 6 valid_and_avoc                                 2418         0.717   1066.   3791.     0    0     29     534.   70156 "▇▁▁▁▁"
 7 valid_and_viewable                                0         1      34801. 131568.     0  138   1564.  12955  2078543 "▇▁▁▁▁"
 8 valid_and_viewable_gm                          6114         0.283 179529. 437351.     5 2276  21661  143106. 3800796 "▇▁▁▁▁"
 9 valid_and_fully_on_screen_3sec_cumulative      8532         0        NaN      NA     NA   NA     NA      NA       NA " "    
10 valid_and_inview_3sec_cumulative               2418         0.717   9809.  29091.     0   50    528.   4958   365068 "▇▁▁▁▁"

-- Variable type: POSIXct ---------------------------------------------------------------------------------------------------------------
# A tibble: 1 x 7
  skim_variable n_missing complete_rate min                 max                 median              n_unique
* <chr>             <int>         <dbl> <dttm>              <dttm>              <dttm>                 <int>
1 date                  0             1 2021-10-21 00:00:00 2022-01-01 00:00:00 2021-12-05 00:00:00       72

Plot Impression Level Data


p = Social_2022_processed_Add2Meta_data %>% 
  ggplot() +
    aes(x = date, y = impressions_analyzed, color = olive_plan_name, fill = olive_plan_name) +
  xlab("Date") +
  ylab("Impressions") +
  ggtitle("Meta Impressions by Campaign") + #fix size
geom_bar(stat = 'identity') +
  theme_bw() +
  theme(
     plot.title = element_text(size=22, hjust = 0.5),
     axis.title.y = element_blank()
  )

p


ggplotly(p)

Calculate V/V and AVOC Rates by Platform

Social_2022_Summarized_Add2Meta_data <-
Social_2022_processed_Add2Meta_data %>%
  mutate(
    valid_viewable_imps =
      case_when(
        platform == 'Twitter' & channel == 'Display' ~ valid_and_inview_3sec_cumulative,
        platform == 'LinkedIn' ~ x2_sec_video_in_view_impressions,
        TRUE ~ valid_and_viewable
      ),
    avoc_imps = case_when(
    is.na(player_vis_and_aud_on_complete_sum) ~ 0,
    TRUE ~  player_vis_and_aud_on_complete_sum 
    ),
    quarter = lubridate::quarter(date),
    channel = case_when(
      channel == 'DISPLAY' ~ 'STATIC',
      TRUE ~ channel
    )
  ) %>% 
  group_by(olive_plan_name,date, channel, platform) %>% 
  summarize(
    valid_viewable_imps = sum(valid_viewable_imps),
    avoc_imps = sum(avoc_imps),
    impressions = sum(impressions_analyzed),
    quarter = max(quarter)
  ) %>% 
  arrange(date,olive_plan_name)
`summarise()` has grouped output by 'olive_plan_name', 'date', 'channel'. You can override using the `.groups` argument.

Summarized Table - Campaign

Sumif Documentation


Social_2022_Summarized_Add2Meta_data %>% 
  group_by(olive_plan_name) %>% 
  summarize(
    `Valid and Viewable Rate` = sum(valid_viewable_imps)/sum(impressions),
    `Video vs Static` = 1 - sum(impressions[channel =='STATIC'])/sum(impressions)
  ) %>%     
  kbl() %>% 
 kable_material(c("striped", "hover","condensed","responsive"),full_width = F,fixed_thead = T)
olive_plan_name Valid and Viewable Rate Video vs Static
Android NA 2021 Q4 2021 North America - Samsung D3 Campaign 0.32632 0.42451
GSA NA 2021 Q4 2021 Global - iGA Futura Brand Q4 2021 0.16121 0.81153

Write to Google Sheets


Social_2022_Summarized_Add2Meta_data_Table <-
Social_2022_Summarized_Add2Meta_data %>% 
  group_by(olive_plan_name) %>% 
  summarize(
    `Valid and Viewable Rate` = sum(valid_viewable_imps)/sum(impressions),
    `Video vs Static` = 1 - sum(impressions[channel =='STATIC'])/sum(impressions)
  )
write_sheet(Social_2022_Summarized_Add2Meta_data_Table, ss = 'https://docs.google.com/spreadsheets/d/1RU0QGpnn7FHtZaZfCA22kCcGpEeY1vLh0pHkJ9DEZfU/edit#gid=1752984558',
           sheet = 'Additional 2 Campaign Data From R')
√ Writing to H1 2022 Meta Ask v2.
√ Writing to sheet Additional 2 Campaign Data From R.
LS0tDQp0aXRsZTogIjAxX0RhdGFfUmVhZGluX1N1bW1hcnlfMjAyMk5BX1NvY2lhbCINCmF1dGhvcjogIkRhcnNoYW4gUGF0ZWwiDQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogbm8NCiAgICB0aGVtZTogY2VydWxlYW4NCiAgICBoaWdobGlnaHQ6IHplbmJ1cm4NCiAgICBmaWdfd2lkdGg6IDcNCiAgICBmaWdfaGVpZ2h0OiA2DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIGRmX3ByaW50OiBwYWdlZA0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KI25vdGU6IG5vcm1hbGx5IGluY2x1ZGUgPSBGQUxTRSBmb3IgdGhpcw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKSAjYWxsIGNvZGUgY2h1bmtzIGJ5IGRlZmF1bHQgd2lsbCBiZSBzaG93bg0Kb3B0aW9ucyhrbml0ci50YWJsZS5mb3JtYXQgPSAiaHRtbCIpICN0YWJsZSBmb3JtYXQNCm9wdGlvbnMoZGlnaXRzPTUpICNzZXQgZGlnaXRzIGluIG51bWJlcnMNCm9wdGlvbnMoc2NpcGVuID0gMTAwKSAjZGlnaXRzIHNob3cgYmVmb3JlIHVzaW5nIHNjaWVudGlmaWMgbm90YXRpb24NCmtuaXRyOjpvcHRzX2NodW5rJHNldCh0aWR5Lm9wdHM9bGlzdCh3aWR0aC5jdXRvZmY9ODApLCB0aWR5PVRSVUUpDQojaW5zdGFsbC5wYWNrYWdlcygicGFjbWFuIikNCmxpYnJhcnkocGFjbWFuKSAjZm9yIHF1aWNrIGxvYWQvaW5zdGFsbCBvZiBwYWNrYWdlcw0KcF9sb2FkKA0KICBkcGx5ciwgcmVhZHIsIHRpZHl2ZXJzZSxmb3JjYXRzLHB1cnJyLGx1YnJpZGF0ZSwgIyByZWFkaW5nIGluIGRhdGENCiAgamFuaXRvciwgc3FsZGYsZ29vZ2xlc2hlZXRzNCwgIyBhZGRpdGlvbmFsIHRvb2xzIGZvciBkZWFsaW5nIHdpdGggZGF0YQ0KICBza2ltciwNCiAgcnFkYXRhdGFibGUsICMNCiAgc3BsaXRzdGFja3NoYXBlLHN0cmluZ3IsICNzdHJpbmcgcmVsYXRlZCBsaWJyYXJpZXMNCiAga2FibGVFeHRyYSwgZ2dwbG90MiwgcGxvdGx5LGVjaGFydHM0cixnZ3B1YnIsc2NhbGVzLFJDb2xvckJyZXdlcixnZ3RoZW1lcywgI2ZvciB2aXN1YWxpemF0aW9uIG9mIGRhdGENCiAgcmV0aWN1bGF0ZSAjZm9yIHVzaW5nIHB5dGhvbg0KKQ0KYGBgDQoNCiMjIERhdGEgUmVhZC1pbg0KDQo8aHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vc3ByZWFkc2hlZXRzL2QvMW5EWG9rY3d0cV9KOEE2VWg3ekF4c1dXMTZNdGNFQ18xRWlMc3R6NFdHaWcvZWRpdCNnaWQ9MTc4Mjk3OTU3MT4NCg0KYGBge3J9DQpTb2NpYWxfMjAyMl9yYXdOQV9kYXRhIDwtIHJlYWRyOjpyZWFkX2NzdigiREFUQS9Tb2NpYWwgUXVlcnkgMjAyMiBOQSBDYW1wYWlnbnMuY3N2IikgJT4lDQogIGNsZWFuX25hbWVzKCkgJT4lIA0KICBmaWx0ZXIoZGF0ZSA8ICcyMDIyLTA3LTAxJykgJT4lIA0KICBmaWx0ZXIoaW1wcmVzc2lvbnNfYW5hbHl6ZWQgPiAxMCkNCg0KDQpTb2NpYWxfMjAyMl9yYXdOQV9sb29rdXAgPC0gcmVhZHI6OnJlYWRfY3N2KCJEQVRBL0NhbXBhaWduTG9va3VwLmNzdiIpICU+JQ0KICBjbGVhbl9uYW1lcygpDQoNClNvY2lhbF8yMDIyX01PQVRfbG9va3VwID0gZ29vZ2xlc2hlZXRzNDo6cmVhZF9zaGVldCgNCiAgImh0dHBzOi8vZG9jcy5nb29nbGUuY29tL3NwcmVhZHNoZWV0cy9kLzFuRFhva2N3dHFfSjhBNlVoN3pBeHNXVzE2TXRjRUNfMUVpTHN0ejRXR2lnL2VkaXQjZ2lkPTE3ODI5Nzk1NzEiKSAlPiUgDQogIGNsZWFuX25hbWVzKCkgJT4lIA0KICBmaWx0ZXIoc29jaWFsID09ICdZJykNCg0KYGBgDQoNCiMjIFN1bW1hcnkgU3RhdHMNCg0KIyMjIFBsYWNlbWVudCB0eXBlcyBkaXN0aW5jdA0KDQpgYGB7cn0NCg0KU29jaWFsXzIwMjJfcmF3TkFfZGF0YSAlPiUNCiAgZ3JvdXBfYnkocGxhdGZvcm0sb2xpdmVfcGxhY2VtZW50X3R5cGUpICU+JSANCiAgc3VtbWFyaXplIChjb3VudHMgPSBuKCkpDQoNClNvY2lhbF8yMDIyX3Jhd05BX2RhdGEgJT4lDQogIGdyb3VwX2J5KHBsYXRmb3JtLGJyYW5kX2lkKSAlPiUgDQogIHN1bW1hcml6ZSAoY291bnRzID0gbigpKSAlPiUNCiAgbGVmdF9qb2luKFNvY2lhbF8yMDIyX01PQVRfbG9va3VwLCBieSA9ICdicmFuZF9pZCcpDQoNCmBgYA0KDQpgYGB7cn0NCg0KU29jaWFsXzIwMjJfcHJvY2Vzc2VkTkFfZGF0YSA8LQ0KICBTb2NpYWxfMjAyMl9yYXdOQV9kYXRhICU+JQ0KICBzZWxlY3QoDQogICAgb2xpdmVfcGxhbl9pZDpvcGlkLCBpbXByZXNzaW9uc19hbmFseXplZCwNCiAgICB4Ml9zZWNfdmlkZW9faW5fdmlld19pbXByZXNzaW9ucywgaW5fdmlld19pbXByZXNzaW9ucywgZnVsbHlfb25fc2NyZWVuXzNzZWNfY3VtdWxhdGl2ZSwgcGxheWVyX3Zpc19hbmRfYXVkX29uX2NvbXBsZXRlX3N1bSwNCiAgICB2YWxpZF9hbmRfYXZvYywgdmFsaWRfYW5kX3ZpZXdhYmxlLCB2YWxpZF9hbmRfdmlld2FibGVfZ20sIHZhbGlkX2FuZF9mdWxseV9vbl9zY3JlZW5fM3NlY19jdW11bGF0aXZlLCB2YWxpZF9hbmRfaW52aWV3XzNzZWNfY3VtdWxhdGl2ZQ0KICApICU+JQ0KICByZW5hbWUocGxhdGZvcm1fb2xkID0gcGxhdGZvcm0NCiAgICAgICAgICkgJT4lIA0KICBsZWZ0X2pvaW4oU29jaWFsXzIwMjJfTU9BVF9sb29rdXAsIGJ5ID0gJ2JyYW5kX2lkJw0KICApICU+JSANCiAgbXV0YXRlKA0KICAgIG9saXZlX3BsYW5faWQgPSBhcy5jaGFyYWN0ZXIob2xpdmVfcGxhbl9pZCksDQogICAgb2xpdmVfcGxhY2VtZW50X2lkID0gYXMuY2hhcmFjdGVyKG9saXZlX3BsYWNlbWVudF9pZCksDQogICAgYnJhbmRfaWQgPSBhcy5jaGFyYWN0ZXIoYnJhbmRfaWQpICwNCiAgICBvcGlkID0gYXMuY2hhcmFjdGVyKG9waWQpDQogICkNCg0KI0xvb2sgYXQgZ2xvYmFsIG1vYXQNCg0KU29jaWFsXzIwMjJfcHJvY2Vzc2VkTkFfZGF0YSAlPiUgDQogIHNraW0oKQ0KYGBgDQoNCiMjIyBQbG90IEltcHJlc3Npb24gTGV2ZWwgRGF0YQ0KDQpgYGB7ciwgZmlnLmhlaWdodD0gMTAsIGZpZy53aWR0aD0gMTV9DQoNCnAgPSBTb2NpYWxfMjAyMl9wcm9jZXNzZWROQV9kYXRhICU+JSANCiAgZ2dwbG90KCkgKw0KICAgIGFlcyh4ID0gZGF0ZSwgeSA9IGltcHJlc3Npb25zX2FuYWx5emVkLCBjb2xvciA9IG9saXZlX3BsYW5fbmFtZSwgZmlsbCA9IG9saXZlX3BsYW5fbmFtZSkgKw0KICB4bGFiKCJEYXRlIikgKw0KICB5bGFiKCJJbXByZXNzaW9ucyIpICsNCiAgZ2d0aXRsZSgiSW1wcmVzc2lvbnMgYnkgQ2FtcGFpZ24iKSArICNmaXggc2l6ZQ0KZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsNCiAgdGhlbWVfYncoKSArDQogIHRoZW1lKA0KICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MjIsIGhqdXN0ID0gMC41KSwNCiAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpDQogICkNCg0KcA0KDQpnZ3Bsb3RseShwKQ0KYGBgDQoNCiMjIyBDYWxjdWxhdGUgVi9WIGFuZCBBVk9DIFJhdGVzIGJ5IFBsYXRmb3JtDQoNCmBgYHtyfQ0KU29jaWFsXzIwMjJfU3VtbWFyaXplZE5BX2RhdGUgPC0NClNvY2lhbF8yMDIyX3Byb2Nlc3NlZE5BX2RhdGEgJT4lDQogIG11dGF0ZSgNCiAgICB2YWxpZF92aWV3YWJsZV9pbXBzID0NCiAgICAgIGNhc2Vfd2hlbigNCiAgICAgICAgcGxhdGZvcm0gPT0gJ1R3aXR0ZXInICYgY2hhbm5lbCA9PSAnRGlzcGxheScgfiB2YWxpZF9hbmRfaW52aWV3XzNzZWNfY3VtdWxhdGl2ZSwNCiAgICAgICAgcGxhdGZvcm0gPT0gJ0xpbmtlZEluJyB+IHgyX3NlY192aWRlb19pbl92aWV3X2ltcHJlc3Npb25zLA0KICAgICAgICBUUlVFIH4gdmFsaWRfYW5kX3ZpZXdhYmxlDQogICAgICApLA0KICAgIGF2b2NfaW1wcyA9IGNhc2Vfd2hlbigNCiAgICBUUlVFIH4gIHBsYXllcl92aXNfYW5kX2F1ZF9vbl9jb21wbGV0ZV9zdW0gDQogICAgKSwNCiAgICBxdWFydGVyID0gbHVicmlkYXRlOjpxdWFydGVyKGRhdGUpLA0KICAgIGNoYW5uZWwgPSBjYXNlX3doZW4oDQogICAgICBjaGFubmVsID09ICdESVNQTEFZJyB+ICdTVEFUSUMnLA0KICAgICAgVFJVRSB+IGNoYW5uZWwNCiAgICApDQogICkgJT4lIA0KICBncm91cF9ieShvbGl2ZV9wbGFuX25hbWUsZGF0ZSwgY2hhbm5lbCwgcGxhdGZvcm0pICU+JSANCiAgc3VtbWFyaXplKA0KICAgIHZhbGlkX3ZpZXdhYmxlX2ltcHMgPSBzdW0odmFsaWRfdmlld2FibGVfaW1wcyksDQogICAgYXZvY19pbXBzID0gc3VtKGF2b2NfaW1wcyksDQogICAgaW1wcmVzc2lvbnMgPSBzdW0oaW1wcmVzc2lvbnNfYW5hbHl6ZWQpLA0KICAgIHF1YXJ0ZXIgPSBtYXgocXVhcnRlcikNCiAgKSAlPiUgDQogIGFycmFuZ2UoZGF0ZSxvbGl2ZV9wbGFuX25hbWUpDQpgYGANCg0KYGBge3J9DQoNClNvY2lhbF8yMDIyX1N1bW1hcml6ZWROQV9kYXRlICU+JSANCiAgZmlsdGVyKHBsYXRmb3JtID09ICdUd2l0dGVyJykgJT4lIA0KICBmaWx0ZXIoY2hhbm5lbCA9PSAnRElTUExBWScpDQoNCmBgYA0KDQpgYGB7cn0NCg0KU29jaWFsXzIwMjJfU3VtbWFyaXplZE5BX2RhdGUgJT4lIA0KICBncm91cF9ieShxdWFydGVyLCBwbGF0Zm9ybSwgY2hhbm5lbCkgJT4lIA0KICBzdW1tYXJpemUoDQogICAgYFZhbGlkIGFuZCBWaWV3YWJsZSBSYXRlYCA9IHN1bSh2YWxpZF92aWV3YWJsZV9pbXBzKS9zdW0oaW1wcmVzc2lvbnMpLA0KICAgIGBBVk9DIFJhdGVgID0gc3VtKGF2b2NfaW1wcykvc3VtKGltcHJlc3Npb25zKQ0KICApICU+JSAgICAgDQogIGtibCgpICU+JSANCiBrYWJsZV9tYXRlcmlhbChjKCJzdHJpcGVkIiwgImhvdmVyIiwiY29uZGVuc2VkIiwicmVzcG9uc2l2ZSIpLGZ1bGxfd2lkdGggPSBGLGZpeGVkX3RoZWFkID0gVCkNCmBgYA0KDQpgYGB7cn0NCndyaXRlX3NoZWV0KFNvY2lhbF8yMDIyX1N1bW1hcml6ZWROQV9kYXRlLCBzcyA9ICdodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xT1Q3em9xYmNuYWRRc1I4ZWhIYnZNZktuOG1pZVdZYS1kVmFDT0hGZGhISS9lZGl0I2dpZD0xNDY5OTc4MDU1JywNCiAgICAgICAgICAgc2hlZXQgPSAnQWdncmVnYXRlZCBEYXRhIE5BJykNCmBgYA0KDQojIyMgQWRkaXRpb25hbCBUd2l0dGVyIExldmVsIEluZm9ybWF0aW9uDQoNCmBgYHtyfQ0KDQpTb2NpYWxfMjAyMl9yYXdOQV9EVjMwX2RhdGEgPC0gcmVhZHI6OnJlYWRfY3N2KCJEQVRBL1NvY2lhbCBRdWVyeSAyMDIyIE5BIERWMzYwLmNzdiIpICU+JQ0KICBjbGVhbl9uYW1lcygpICU+JSANCiAgZmlsdGVyKGRhdGUgPCAnMjAyMi0wNy0wMScpICU+JSANCiAgbXV0YXRlKA0KICAgIG9saXZlX3BsYWNlbWVudF9pZCA9IGFzLmNoYXJhY3RlcihvbGl2ZV9wbGFjZW1lbnRfaWQpDQogICkNCiAgDQoNClNvY2lhbF8yMDIyX3Byb2Nlc3NlZFR3aXR0ZXJOQV9kYXRhIDwtDQpTb2NpYWxfMjAyMl9wcm9jZXNzZWROQV9kYXRhICU+JSBzZWxlY3Qob2xpdmVfcGxhbl9uYW1lLG9saXZlX3BsYWNlbWVudF9pZCxkYXRlLGltcHJlc3Npb25zX2FuYWx5emVkKSAlPiUNCiAgbXV0YXRlKA0KICAgIHF1YXJ0ZXIgPSBxdWFydGVyKGRhdGUpDQogICkgJT4lIA0KICBncm91cF9ieShvbGl2ZV9wbGFuX25hbWUsb2xpdmVfcGxhY2VtZW50X2lkLGRhdGUscXVhcnRlcikgJT4lIA0KICBzdW1tYXJpemUoDQogICAgaW1wcmVzc2lvbnNfYW5hbHl6ZWQgPSBzdW0oaW1wcmVzc2lvbnNfYW5hbHl6ZWQpDQogICkgJT4lDQogIHVuZ3JvdXAoKSAlPiUgDQogIGxlZnRfam9pbihTb2NpYWxfMjAyMl9yYXdOQV9EVjMwX2RhdGEsIGJ5ID0gYygnb2xpdmVfcGxhY2VtZW50X2lkJywnb2xpdmVfcGxhbl9uYW1lJywgJ2RhdGUnKSkgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKG9saXZlX3BsYW5fbmFtZSkpICU+JSANCiAgZmlsdGVyKHBsYXRmb3JtID09ICdUd2l0dGVyIC0gT2ZmaWNpYWwnICYgb2xpdmVfcGxhY2VtZW50X3R5cGUgPT0gJ1N0YW5kYXJkIEJhbm5lciAoQkFOKScpICU+JSANCiAgbXV0YXRlKA0KICAgIGltcHJlc3Npb25zID0gaW1wcmVzc2lvbnNfYW5hbHl6ZWQsDQogICAgcGxhdGZvcm0gPSAnVHdpdHRlcicsDQogICAgY2hhbm5lbCA9ICdTVEFUSUMnLA0KICAgIGF2b2NfaW1wcyA9IE5BLA0KICAgIHZhbGlkX3ZpZXdhYmxlX2ltcHMgPSB2YWxpZF9hbmRfdmlld2FibGVfaW1wcmVzc2lvbnMsDQogICAgVGltZSA9IE5BDQogICkgJT4lIA0KICBzZWxlY3Qob2xpdmVfcGxhbl9uYW1lLAlkYXRlLAljaGFubmVsLAlwbGF0Zm9ybSwJdmFsaWRfdmlld2FibGVfaW1wcywJYXZvY19pbXBzLAlpbXByZXNzaW9ucywJVGltZSwJcXVhcnRlcikNCg0KYGBgDQoNCmBgYHtyfQ0KDQpTb2NpYWxfMjAyMl9TdW1tYXJpemVkTkFfZGF0YV91cGRhdGVkVHdpdHRlciA8LQ0KU29jaWFsXzIwMjJfU3VtbWFyaXplZE5BX2RhdGUgJT4lDQogIGZpbHRlcighKHBsYXRmb3JtID09ICdUd2l0dGVyJyAmIGNoYW5uZWwgPT0gJ1NUQVRJQycpKSAlPiUgICANCiAgYmluZF9yb3dzIChTb2NpYWxfMjAyMl9wcm9jZXNzZWRUd2l0dGVyTkFfZGF0YSkNCg0KYGBgDQoNCiMjIyBVcGRhdGUgVHdpdHRlciBJbmZvcm1hdGlvbg0KDQpgYGB7cn0NCg0KDQp3cml0ZV9zaGVldChTb2NpYWxfMjAyMl9TdW1tYXJpemVkTkFfZGF0YV91cGRhdGVkVHdpdHRlciwgc3MgPSAnaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vc3ByZWFkc2hlZXRzL2QvMU9UN3pvcWJjbmFkUXNSOGVoSGJ2TWZLbjhtaWVXWWEtZFZhQ09IRmRoSEkvZWRpdCNnaWQ9MTQ2OTk3ODA1NScsDQogICAgICAgICAgIHNoZWV0ID0gJ0FkZGl0aW9uYWwgTkEgVHdpdHRlciBEYXRhJykNCg0KYGBgDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIEgxIDIwMjIgTWV0YSBBc2sgKFRvcCA3IENhbXBhaWducykNCg0KIyMgRGF0YSBSZWFkLWluDQoNCltHb29nbGUgU2hlZXQgd2l0aCBCUSBSZXN1bHRzXShodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xUlUwUUdwbm43Rkh0WmFaZkNBMjJrQ2NHcEVlWTF2TGgwcEhrSjlERVpmVS9lZGl0I2dpZD0xNzUyOTg0NTU4KQ0KDQpgYGB7cn0NClNvY2lhbF8yMDIyX3Jhd19Ub3A3TWV0YV9kYXRhID0gZ29vZ2xlc2hlZXRzNDo6cmVhZF9zaGVldCgNCiAgImh0dHBzOi8vZG9jcy5nb29nbGUuY29tL3NwcmVhZHNoZWV0cy9kLzFSVTBRR3BubjdGSHRaYVpmQ0EyMmtDY0dwRWVZMXZMaDBwSGtKOURFWmZVL2VkaXQjZ2lkPTE3NTI5ODQ1NTgiKSAlPiUgDQogIGNsZWFuX25hbWVzKCkgJT4lIA0KICBmaWx0ZXIoaW1wcmVzc2lvbnNfYW5hbHl6ZWQgPiAxMCkNCg0KDQpTb2NpYWxfMjAyMl9NT0FUX2xvb2t1cCA9IGdvb2dsZXNoZWV0czQ6OnJlYWRfc2hlZXQoDQogICJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xbkRYb2tjd3RxX0o4QTZVaDd6QXhzV1cxNk10Y0VDXzFFaUxzdHo0V0dpZy9lZGl0I2dpZD0xNzgyOTc5NTcxIikgJT4lIA0KICBjbGVhbl9uYW1lcygpICU+JSANCiAgZmlsdGVyKHNvY2lhbCA9PSAnWScpDQpgYGANCg0KYGBge3J9DQoNClNvY2lhbF8yMDIyX3Jhd19Ub3A3TWV0YV9kYXRhICU+JSANCiAgZ3JvdXBfYnkocGxhdGZvcm0pICU+JSANCiAgc3VtbWFyaXplKGRpc3QgPSBuKCkpDQpgYGANCg0KYGBge3J9DQoNClNvY2lhbF8yMDIyX3Byb2Nlc3NlZF9Ub3A3TWV0YV9kYXRhIDwtDQogIFNvY2lhbF8yMDIyX3Jhd19Ub3A3TWV0YV9kYXRhICU+JQ0KICBmaWx0ZXIocGxhdGZvcm0gPT0gJ0ZhY2Vib29rJykgJT4lIA0KICBzZWxlY3QoDQogICAgb2xpdmVfcGxhbl9pZDpvcGlkLCBpbXByZXNzaW9uc19hbmFseXplZCwNCiAgICB4Ml9zZWNfdmlkZW9faW5fdmlld19pbXByZXNzaW9ucywgaW5fdmlld19pbXByZXNzaW9ucywgZnVsbHlfb25fc2NyZWVuXzNzZWNfY3VtdWxhdGl2ZSwgcGxheWVyX3Zpc19hbmRfYXVkX29uX2NvbXBsZXRlX3N1bSwNCiAgICB2YWxpZF9hbmRfYXZvYywgdmFsaWRfYW5kX3ZpZXdhYmxlLCB2YWxpZF9hbmRfdmlld2FibGVfZ20sIHZhbGlkX2FuZF9mdWxseV9vbl9zY3JlZW5fM3NlY19jdW11bGF0aXZlLCB2YWxpZF9hbmRfaW52aWV3XzNzZWNfY3VtdWxhdGl2ZQ0KICApICU+JQ0KICByZW5hbWUocGxhdGZvcm1fb2xkID0gcGxhdGZvcm0NCiAgICAgICAgICkgJT4lIA0KICBsZWZ0X2pvaW4oU29jaWFsXzIwMjJfTU9BVF9sb29rdXAsIGJ5ID0gJ2JyYW5kX2lkJw0KICApICU+JSANCiAgbXV0YXRlKA0KICAgIG9saXZlX3BsYW5faWQgPSBhcy5jaGFyYWN0ZXIob2xpdmVfcGxhbl9pZCksDQogICAgb2xpdmVfcGxhY2VtZW50X2lkID0gYXMuY2hhcmFjdGVyKG9saXZlX3BsYWNlbWVudF9pZCksDQogICAgYnJhbmRfaWQgPSBhcy5jaGFyYWN0ZXIoYnJhbmRfaWQpICwNCiAgICBvcGlkID0gYXMuY2hhcmFjdGVyKG9waWQpDQogICkNCg0KI0NoZWNrIE1pc3NpbmcgRGF0YQ0KDQpTb2NpYWxfMjAyMl9wcm9jZXNzZWRfVG9wN01ldGFfZGF0YSAlPiUgDQogIHNraW0oKQ0KDQpgYGANCg0KIyMjIFBsb3QgSW1wcmVzc2lvbiBMZXZlbCBEYXRhDQoNCmBgYHtyLCBmaWcuaGVpZ2h0PSAxMCwgZmlnLndpZHRoPSAyMH0NCg0KcCA9IFNvY2lhbF8yMDIyX3Byb2Nlc3NlZF9Ub3A3TWV0YV9kYXRhICU+JSANCiAgZ2dwbG90KCkgKw0KICAgIGFlcyh4ID0gZGF0ZSwgeSA9IGltcHJlc3Npb25zX2FuYWx5emVkLCBjb2xvciA9IG9saXZlX3BsYW5fbmFtZSwgZmlsbCA9IG9saXZlX3BsYW5fbmFtZSkgKw0KICB4bGFiKCJEYXRlIikgKw0KICB5bGFiKCJJbXByZXNzaW9ucyIpICsNCiAgZ2d0aXRsZSgiTWV0YSBJbXByZXNzaW9ucyBieSBDYW1wYWlnbiIpICsgI2ZpeCBzaXplDQpnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKw0KICB0aGVtZV9idygpICsNCiAgdGhlbWUoDQogICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMiwgaGp1c3QgPSAwLjUpLA0KICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCkNCiAgKQ0KDQpwDQoNCmdncGxvdGx5KHApDQpgYGANCg0KIyMjIENhbGN1bGF0ZSBWL1YgYW5kIEFWT0MgUmF0ZXMgYnkgUGxhdGZvcm0NCg0KYGBge3J9DQpTb2NpYWxfMjAyMl9TdW1tYXJpemVkX1RvcDdNZXRhX2RhdGEgPC0NClNvY2lhbF8yMDIyX3Byb2Nlc3NlZF9Ub3A3TWV0YV9kYXRhICU+JQ0KICBtdXRhdGUoDQogICAgdmFsaWRfdmlld2FibGVfaW1wcyA9DQogICAgICBjYXNlX3doZW4oDQogICAgICAgIHBsYXRmb3JtID09ICdUd2l0dGVyJyAmIGNoYW5uZWwgPT0gJ0Rpc3BsYXknIH4gdmFsaWRfYW5kX2ludmlld18zc2VjX2N1bXVsYXRpdmUsDQogICAgICAgIHBsYXRmb3JtID09ICdMaW5rZWRJbicgfiB4Ml9zZWNfdmlkZW9faW5fdmlld19pbXByZXNzaW9ucywNCiAgICAgICAgVFJVRSB+IHZhbGlkX2FuZF92aWV3YWJsZQ0KICAgICAgKSwNCiAgICBhdm9jX2ltcHMgPSBjYXNlX3doZW4oDQogICAgaXMubmEocGxheWVyX3Zpc19hbmRfYXVkX29uX2NvbXBsZXRlX3N1bSkgfiAwLA0KICAgIFRSVUUgfiAgcGxheWVyX3Zpc19hbmRfYXVkX29uX2NvbXBsZXRlX3N1bSANCiAgICApLA0KICAgIHF1YXJ0ZXIgPSBsdWJyaWRhdGU6OnF1YXJ0ZXIoZGF0ZSksDQogICAgY2hhbm5lbCA9IGNhc2Vfd2hlbigNCiAgICAgIGNoYW5uZWwgPT0gJ0RJU1BMQVknIH4gJ1NUQVRJQycsDQogICAgICBUUlVFIH4gY2hhbm5lbA0KICAgICkNCiAgKSAlPiUgDQogIGdyb3VwX2J5KG9saXZlX3BsYW5fbmFtZSxkYXRlLCBjaGFubmVsLCBwbGF0Zm9ybSkgJT4lIA0KICBzdW1tYXJpemUoDQogICAgdmFsaWRfdmlld2FibGVfaW1wcyA9IHN1bSh2YWxpZF92aWV3YWJsZV9pbXBzKSwNCiAgICBhdm9jX2ltcHMgPSBzdW0oYXZvY19pbXBzKSwNCiAgICBpbXByZXNzaW9ucyA9IHN1bShpbXByZXNzaW9uc19hbmFseXplZCksDQogICAgcXVhcnRlciA9IG1heChxdWFydGVyKQ0KICApICU+JSANCiAgYXJyYW5nZShkYXRlLG9saXZlX3BsYW5fbmFtZSkNCmBgYA0KDQojIyMgU3VtbWFyaXplZCBUYWJsZSAtIENhbXBhaWduDQoNCltTdW1pZiBEb2N1bWVudGF0aW9uXShodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8yMzUyODg2Mi9zdW1tYXJpemUtYWxsLWdyb3VwLXZhbHVlcy1hbmQtYS1jb25kaXRpb25hbC1zdWJzZXQtaW4tdGhlLXNhbWUtY2FsbCkNCg0KYGBge3J9DQoNClNvY2lhbF8yMDIyX1N1bW1hcml6ZWRfVG9wN01ldGFfZGF0YSAlPiUgDQogIGdyb3VwX2J5KG9saXZlX3BsYW5fbmFtZSkgJT4lIA0KICBzdW1tYXJpemUoDQogICAgYFZhbGlkIGFuZCBWaWV3YWJsZSBSYXRlYCA9IHN1bSh2YWxpZF92aWV3YWJsZV9pbXBzKS9zdW0oaW1wcmVzc2lvbnMpLA0KICAgIGBWaWRlbyB2cyBTdGF0aWNgID0gMSAtIHN1bShpbXByZXNzaW9uc1tjaGFubmVsID09J1NUQVRJQyddKS9zdW0oaW1wcmVzc2lvbnMpDQogICkgJT4lICAgICANCiAga2JsKCkgJT4lIA0KIGthYmxlX21hdGVyaWFsKGMoInN0cmlwZWQiLCAiaG92ZXIiLCJjb25kZW5zZWQiLCJyZXNwb25zaXZlIiksZnVsbF93aWR0aCA9IEYsZml4ZWRfdGhlYWQgPSBUKQ0KYGBgDQoNCiMjIyBXcml0ZSB0byBHb29nbGUgU2hlZXRzDQoNCmBgYHtyfQ0KDQpTb2NpYWxfMjAyMl9TdW1tYXJpemVkX1RvcDdNZXRhX2RhdGFfVGFibGUgPC0NClNvY2lhbF8yMDIyX1N1bW1hcml6ZWRfVG9wN01ldGFfZGF0YSAlPiUgDQogIGdyb3VwX2J5KG9saXZlX3BsYW5fbmFtZSkgJT4lIA0KICBzdW1tYXJpemUoDQogICAgYFZhbGlkIGFuZCBWaWV3YWJsZSBSYXRlYCA9IHN1bSh2YWxpZF92aWV3YWJsZV9pbXBzKS9zdW0oaW1wcmVzc2lvbnMpLA0KICAgIGBWaWRlbyB2cyBTdGF0aWNgID0gMSAtIHN1bShpbXByZXNzaW9uc1tjaGFubmVsID09J1NUQVRJQyddKS9zdW0oaW1wcmVzc2lvbnMpDQogICkNCg0KYGBgDQoNCmBgYHtyfQ0Kd3JpdGVfc2hlZXQoU29jaWFsXzIwMjJfU3VtbWFyaXplZF9Ub3A3TWV0YV9kYXRhX1RhYmxlLCBzcyA9ICdodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xUlUwUUdwbm43Rkh0WmFaZkNBMjJrQ2NHcEVlWTF2TGgwcEhrSjlERVpmVS9lZGl0I2dpZD0xNzUyOTg0NTU4JywNCiAgICAgICAgICAgc2hlZXQgPSAnQWdncmVnYXRlZCBEYXRhIEZyb20gUicpDQpgYGANCg0KDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIEgxIDIwMjIgTWV0YSBBc2sgKEFkZGl0aW9uYWwgMiBDYW1wYWlnbnMpDQoNCiMjIERhdGEgUmVhZC1pbg0KDQpbR29vZ2xlIFNoZWV0IHdpdGggQlEgUmVzdWx0c10oaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vc3ByZWFkc2hlZXRzL2QvMTlNdkJLWGNCdHY5V2huNHV4YXJLR3Z1TERvRWdzZnJMcklUUGJ0Mmpmcm8vZWRpdCNnaWQ9MzcyNTk0MzEwKQ0KDQpgYGB7cn0NClNvY2lhbF8yMDIyX3Jhd19BZGQyTWV0YV9kYXRhID0gZ29vZ2xlc2hlZXRzNDo6cmVhZF9zaGVldCgNCiAgImh0dHBzOi8vZG9jcy5nb29nbGUuY29tL3NwcmVhZHNoZWV0cy9kLzFZZGtFU29ZbHY2ZnpwUVk4NGo0QUI3THc1cWZXOFhLUG1oMkIwZ0FwWUpBL2VkaXQjZ2lkPTE5ODAyMDgxNDAiKSAlPiUgDQogIGNsZWFuX25hbWVzKCkgJT4lIA0KICBmaWx0ZXIoaW1wcmVzc2lvbnNfYW5hbHl6ZWQgPiAxMCkNCg0KDQpTb2NpYWxfMjAyMl9NT0FUX2xvb2t1cCA9IGdvb2dsZXNoZWV0czQ6OnJlYWRfc2hlZXQoDQogICJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xbkRYb2tjd3RxX0o4QTZVaDd6QXhzV1cxNk10Y0VDXzFFaUxzdHo0V0dpZy9lZGl0I2dpZD0xNzgyOTc5NTcxIikgJT4lIA0KICBjbGVhbl9uYW1lcygpICU+JSANCiAgZmlsdGVyKHNvY2lhbCA9PSAnWScpDQpgYGANCg0KYGBge3J9DQoNClNvY2lhbF8yMDIyX3Jhd19BZGQyTWV0YV9kYXRhICU+JSANCiAgZ3JvdXBfYnkocGxhdGZvcm0pICU+JSANCiAgc3VtbWFyaXplKGRpc3QgPSBuKCkpDQpgYGANCg0KYGBge3J9DQoNClNvY2lhbF8yMDIyX3Byb2Nlc3NlZF9BZGQyTWV0YV9kYXRhIDwtDQogIFNvY2lhbF8yMDIyX3Jhd19BZGQyTWV0YV9kYXRhICU+JQ0KICBmaWx0ZXIocGxhdGZvcm0gPT0gJ0ZhY2Vib29rJ3xwbGF0Zm9ybSA9PSAnRmFjZWJvb2svSW5zdGFncmFtJykgJT4lIA0KICBzZWxlY3QoDQogICAgb2xpdmVfcGxhbl9pZDpvcGlkLCBpbXByZXNzaW9uc19hbmFseXplZCwNCiAgICB4Ml9zZWNfdmlkZW9faW5fdmlld19pbXByZXNzaW9ucywgaW5fdmlld19pbXByZXNzaW9ucywgZnVsbHlfb25fc2NyZWVuXzNzZWNfY3VtdWxhdGl2ZSwgcGxheWVyX3Zpc19hbmRfYXVkX29uX2NvbXBsZXRlX3N1bSwNCiAgICB2YWxpZF9hbmRfYXZvYywgdmFsaWRfYW5kX3ZpZXdhYmxlLCB2YWxpZF9hbmRfdmlld2FibGVfZ20sIHZhbGlkX2FuZF9mdWxseV9vbl9zY3JlZW5fM3NlY19jdW11bGF0aXZlLCB2YWxpZF9hbmRfaW52aWV3XzNzZWNfY3VtdWxhdGl2ZQ0KICApICU+JQ0KICByZW5hbWUocGxhdGZvcm1fb2xkID0gcGxhdGZvcm0NCiAgICAgICAgICkgJT4lIA0KICBsZWZ0X2pvaW4oU29jaWFsXzIwMjJfTU9BVF9sb29rdXAsIGJ5ID0gJ2JyYW5kX2lkJw0KICApICU+JSANCiAgbXV0YXRlKA0KICAgIG9saXZlX3BsYW5faWQgPSBhcy5jaGFyYWN0ZXIob2xpdmVfcGxhbl9pZCksDQogICAgb2xpdmVfcGxhY2VtZW50X2lkID0gYXMuY2hhcmFjdGVyKG9saXZlX3BsYWNlbWVudF9pZCksDQogICAgYnJhbmRfaWQgPSBhcy5jaGFyYWN0ZXIoYnJhbmRfaWQpICwNCiAgICBvcGlkID0gYXMuY2hhcmFjdGVyKG9waWQpDQogICkNCg0KI0NoZWNrIE1pc3NpbmcgRGF0YQ0KDQpTb2NpYWxfMjAyMl9wcm9jZXNzZWRfQWRkMk1ldGFfZGF0YSAlPiUgDQogIHNraW0oKQ0KDQpgYGANCg0KIyMjIFBsb3QgSW1wcmVzc2lvbiBMZXZlbCBEYXRhDQoNCmBgYHtyLCBmaWcuaGVpZ2h0PSAxMCwgZmlnLndpZHRoPSAyMH0NCg0KcCA9IFNvY2lhbF8yMDIyX3Byb2Nlc3NlZF9BZGQyTWV0YV9kYXRhICU+JSANCiAgZ2dwbG90KCkgKw0KICAgIGFlcyh4ID0gZGF0ZSwgeSA9IGltcHJlc3Npb25zX2FuYWx5emVkLCBjb2xvciA9IG9saXZlX3BsYW5fbmFtZSwgZmlsbCA9IG9saXZlX3BsYW5fbmFtZSkgKw0KICB4bGFiKCJEYXRlIikgKw0KICB5bGFiKCJJbXByZXNzaW9ucyIpICsNCiAgZ2d0aXRsZSgiTWV0YSBJbXByZXNzaW9ucyBieSBDYW1wYWlnbiIpICsgI2ZpeCBzaXplDQpnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKw0KICB0aGVtZV9idygpICsNCiAgdGhlbWUoDQogICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0yMiwgaGp1c3QgPSAwLjUpLA0KICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCkNCiAgKQ0KDQpwDQoNCmdncGxvdGx5KHApDQpgYGANCg0KIyMjIENhbGN1bGF0ZSBWL1YgYW5kIEFWT0MgUmF0ZXMgYnkgUGxhdGZvcm0NCg0KYGBge3J9DQpTb2NpYWxfMjAyMl9TdW1tYXJpemVkX0FkZDJNZXRhX2RhdGEgPC0NClNvY2lhbF8yMDIyX3Byb2Nlc3NlZF9BZGQyTWV0YV9kYXRhICU+JQ0KICBtdXRhdGUoDQogICAgdmFsaWRfdmlld2FibGVfaW1wcyA9DQogICAgICBjYXNlX3doZW4oDQogICAgICAgIHBsYXRmb3JtID09ICdUd2l0dGVyJyAmIGNoYW5uZWwgPT0gJ0Rpc3BsYXknIH4gdmFsaWRfYW5kX2ludmlld18zc2VjX2N1bXVsYXRpdmUsDQogICAgICAgIHBsYXRmb3JtID09ICdMaW5rZWRJbicgfiB4Ml9zZWNfdmlkZW9faW5fdmlld19pbXByZXNzaW9ucywNCiAgICAgICAgVFJVRSB+IHZhbGlkX2FuZF92aWV3YWJsZQ0KICAgICAgKSwNCiAgICBhdm9jX2ltcHMgPSBjYXNlX3doZW4oDQogICAgaXMubmEocGxheWVyX3Zpc19hbmRfYXVkX29uX2NvbXBsZXRlX3N1bSkgfiAwLA0KICAgIFRSVUUgfiAgcGxheWVyX3Zpc19hbmRfYXVkX29uX2NvbXBsZXRlX3N1bSANCiAgICApLA0KICAgIHF1YXJ0ZXIgPSBsdWJyaWRhdGU6OnF1YXJ0ZXIoZGF0ZSksDQogICAgY2hhbm5lbCA9IGNhc2Vfd2hlbigNCiAgICAgIGNoYW5uZWwgPT0gJ0RJU1BMQVknIH4gJ1NUQVRJQycsDQogICAgICBUUlVFIH4gY2hhbm5lbA0KICAgICkNCiAgKSAlPiUgDQogIGdyb3VwX2J5KG9saXZlX3BsYW5fbmFtZSxkYXRlLCBjaGFubmVsLCBwbGF0Zm9ybSkgJT4lIA0KICBzdW1tYXJpemUoDQogICAgdmFsaWRfdmlld2FibGVfaW1wcyA9IHN1bSh2YWxpZF92aWV3YWJsZV9pbXBzKSwNCiAgICBhdm9jX2ltcHMgPSBzdW0oYXZvY19pbXBzKSwNCiAgICBpbXByZXNzaW9ucyA9IHN1bShpbXByZXNzaW9uc19hbmFseXplZCksDQogICAgcXVhcnRlciA9IG1heChxdWFydGVyKQ0KICApICU+JSANCiAgYXJyYW5nZShkYXRlLG9saXZlX3BsYW5fbmFtZSkNCmBgYA0KDQojIyMgU3VtbWFyaXplZCBUYWJsZSAtIENhbXBhaWduDQoNCltTdW1pZiBEb2N1bWVudGF0aW9uXShodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8yMzUyODg2Mi9zdW1tYXJpemUtYWxsLWdyb3VwLXZhbHVlcy1hbmQtYS1jb25kaXRpb25hbC1zdWJzZXQtaW4tdGhlLXNhbWUtY2FsbCkNCg0KYGBge3J9DQoNClNvY2lhbF8yMDIyX1N1bW1hcml6ZWRfQWRkMk1ldGFfZGF0YSAlPiUgDQogIGdyb3VwX2J5KG9saXZlX3BsYW5fbmFtZSkgJT4lIA0KICBzdW1tYXJpemUoDQogICAgYFZhbGlkIGFuZCBWaWV3YWJsZSBSYXRlYCA9IHN1bSh2YWxpZF92aWV3YWJsZV9pbXBzKS9zdW0oaW1wcmVzc2lvbnMpLA0KICAgIGBWaWRlbyB2cyBTdGF0aWNgID0gMSAtIHN1bShpbXByZXNzaW9uc1tjaGFubmVsID09J1NUQVRJQyddKS9zdW0oaW1wcmVzc2lvbnMpDQogICkgJT4lICAgICANCiAga2JsKCkgJT4lIA0KIGthYmxlX21hdGVyaWFsKGMoInN0cmlwZWQiLCAiaG92ZXIiLCJjb25kZW5zZWQiLCJyZXNwb25zaXZlIiksZnVsbF93aWR0aCA9IEYsZml4ZWRfdGhlYWQgPSBUKQ0KYGBgDQoNCiMjIyBXcml0ZSB0byBHb29nbGUgU2hlZXRzDQoNCmBgYHtyfQ0KDQpTb2NpYWxfMjAyMl9TdW1tYXJpemVkX0FkZDJNZXRhX2RhdGFfVGFibGUgPC0NClNvY2lhbF8yMDIyX1N1bW1hcml6ZWRfQWRkMk1ldGFfZGF0YSAlPiUgDQogIGdyb3VwX2J5KG9saXZlX3BsYW5fbmFtZSkgJT4lIA0KICBzdW1tYXJpemUoDQogICAgYFZhbGlkIGFuZCBWaWV3YWJsZSBSYXRlYCA9IHN1bSh2YWxpZF92aWV3YWJsZV9pbXBzKS9zdW0oaW1wcmVzc2lvbnMpLA0KICAgIGBWaWRlbyB2cyBTdGF0aWNgID0gMSAtIHN1bShpbXByZXNzaW9uc1tjaGFubmVsID09J1NUQVRJQyddKS9zdW0oaW1wcmVzc2lvbnMpDQogICkNCg0KYGBgDQoNCmBgYHtyfQ0Kd3JpdGVfc2hlZXQoU29jaWFsXzIwMjJfU3VtbWFyaXplZF9BZGQyTWV0YV9kYXRhX1RhYmxlLCBzcyA9ICdodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xUlUwUUdwbm43Rkh0WmFaZkNBMjJrQ2NHcEVlWTF2TGgwcEhrSjlERVpmVS9lZGl0I2dpZD0xNzUyOTg0NTU4JywNCiAgICAgICAgICAgc2hlZXQgPSAnQWRkaXRpb25hbCAyIENhbXBhaWduIERhdGEgRnJvbSBSJykNCmBgYA0KDQoNCg==